package edu.nmt.cs.cse326.team4.crap;

import java.io.Serializable;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;

import android.annotation.SuppressLint;

import com.google.android.gms.maps.model.LatLng;

/** A toilet. */
public class Toilet implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	static String[] weekdays = new DateFormatSymbols().getWeekdays();
	
	// basic info
	private int id;
	private double lat, lng;
	private String name, address, city, state; // name and address
	private int zip; // zip code
	
	// rating info
	private float rating = 0; // avg rating
	private int votes = 0; // number of ratings
	
	// additional info
	private ArrayList<String> amenities; // maps quantities to their amenities - for boolean amenities, quantity = 1
	private Map<String,Integer[]> hours; // hours of operation in minutes. first value is open time, second value is close time.
	private String photo = "/drawable/toilet_black.png"; // path to photo of toilet
	private LinkedList<Comment> comments;
	
	
	/** A toilet at 0,0. */
	public Toilet() {
		// initialize amenity list
		amenities = new ArrayList<String>();
		// initialize hours of operation to open all the time
		hours = new HashMap<String,Integer[]>();
		Integer[] times = {0,1439}; // 00:00 - 23:59
		for (String day : Arrays.asList(weekdays))
			hours.put(day, times);
	}
	
	/** A toilet located at lat,lng. */
	public Toilet(double lat, double lng) {
		setLocation(lat,lng);
	}
	
	/** A toilet located at lat,lng. */
	public Toilet(LatLng latLng) {
		setLocation(latLng);
	}
	
	/** A toilet with a name located at lat,lng. */
	public Toilet(String name, double lat, double lng) {
		setLocation(lat,lng);
		setName(name);
	}
	
	/** A toilet with a name located at lat,lng. */
	public Toilet(String name, LatLng latLng) {
		setLocation(latLng);
		setName(name);
	}
	
	/** A toilet with everything */
	public Toilet(String name, 
			LatLng latLng, 
			String address, 
			String city, 
			String state, 
			int zip, 
			float rating, 
			int votes, 
			ArrayList<String> amenities, 
			Map<String, Integer[]> hours, 
			String photo,
			LinkedList<Comment> hashSet) {
		this.name = name;
		this.lat = latLng.latitude;
		this.lng = latLng.longitude;
		this.address = address;
		this.state = state;
		this.city = city;
		this.zip = zip;
		this.votes = votes;
		this.rating = rating;
		this.amenities = amenities;
		this.hours = hours;
		this.photo = photo;
		this.comments = hashSet;
	}
	
	/** A toilet with everything */
	public Toilet(int id,
			String name, 
			LatLng latLng, 
			String address, 
			String city, 
			String state, 
			int zip, 
			float rating, 
			int votes, 
			ArrayList<String> amenities, 
			Map<String, Integer[]> hours, 
			String photo,
			LinkedList<Comment> hashSet) {
		this.id = id;
		this.name = name;
		this.lat = latLng.latitude;
		this.lng = latLng.longitude;
		this.address = address;
		this.state = state;
		this.city = city;
		this.zip = zip;
		this.votes = votes;
		this.rating = rating;
		this.amenities = amenities;
		this.hours = hours;
		this.photo = photo;
		this.comments = hashSet;
	}
	
	/** A toilet with everything */
	public Toilet(int id,
			String name,
			double lat,
			double lng,
			String address, 
			String city, 
			String state, 
			int zip, 
			float rating, 
			int votes, 
			ArrayList<String> amenities, 
			Map<String, Integer[]> hours, 
			String photo,
			LinkedList<Comment> hashSet) {
		this.id = id;
		this.name = name;
		this.lat = lat;
		this.lng = lng;
		this.address = address;
		this.state = state;
		this.city = city;
		this.zip = zip;
		this.votes = votes;
		this.rating = rating;
		this.amenities = amenities;
		this.hours = hours;
		this.photo = photo;
		this.comments = hashSet;
	}
	
	/** A toilet with alot of things */
	public Toilet(int id,
			String name, 
			double lat,
			double lng,
			String address,
			float rating, 
			int votes) {
		this.id = id;
		this.name = name;
		this.lat = lat;
		this.lng = lng;
		this.address = address;
		this.votes = votes;
		this.rating = rating;
	}
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	/** Set location of toilet. */
	public void setLocation(double lat, double lng) {
		this.lat = lat;
		this.lng = lng;
	}

	/** Set location of toilet. */
	public void setLocation(LatLng latLng) {
		this.lat = latLng.latitude;
		this.lng = latLng.longitude;
	}

	/** Get location of toilet. */
	public LatLng getLocation() {
		return new LatLng(lat, lng);
	}

	/** Set the toilet's name. */
	public void setName(String name) {
		this.name = name;
	}

	/** Get the toilet's name. */
	public String getName() {
		return name;
	}
	
	/** Set the toilet's address (e.g., address, city, state, zip). */
	public void setAddress(String address, String city, String state, int zip) {
		// TODO: validate the address
		this.address = address;
		this.city = city;
		this.state = state;
		this.zip = zip;
	}
	
	// TODO: setting individual components of an address (e.g., address, city, state, zip)
	
	/** Get the toilet's address in the form "801 Leroy Pl, Socorro, NM 87801" */
	@SuppressLint("DefaultLocale")
	public String getAddress() {
		return String.format("%s,  %s %s %d",address,city,state,zip);
	}
	
	// TODO: getting individual components of an address (e.g., address, city, state, zip)
	
	/** Add an amenity (e.g., diaper changing station) to the toilet. */
	public void addAmenity(String amenity) {
		if (amenities == null)
			amenities = new ArrayList<String>();
		if (amenity != null)
			amenities.add(amenity);
	}
	
	/** Remove an amenity from the toilet. */
	public void removeAmenity(String key, int value) {
		amenities.remove(key);
	}
	
	/** Get a toilet's amenities. */
	public ArrayList<String> getAmenities() {
		return amenities;
	}

	/** Check if the toilet has a particular amenity. */
	public boolean hasAmenity(String amenity) {
		return amenities.indexOf(amenity) != -1 ? true : false;
	}

	/** Set the toilet's hours of operation (in UTC). */
	@SuppressWarnings("deprecation")
	public int setHours(String open, String close) {
		try {
			Date date = new SimpleDateFormat("hh:mm", Locale.US).parse(open);
			int openMinute = date.getHours()*60 + date.getMinutes();
			date = new SimpleDateFormat("hh:mm", Locale.US).parse(close);
			int closeMinute = date.getHours()*60 + date.getMinutes();
			Integer[] times = {openMinute, closeMinute};

			for (int i = 0; i < weekdays.length; i++)
				hours.put(weekdays[i], times);
		} catch (ParseException e1) {
			return 1;
		}
		return 0;
	}

	/** Set the toilet's hours of operation (in UTC) for a certain day. */
	@SuppressWarnings("deprecation")
	public int setHours(String open, String close, String day) {
		try {
			Date date = new SimpleDateFormat("hh:mm", Locale.US).parse(open);
			int openMinute = date.getHours()*60 + date.getMinutes();
			date = new SimpleDateFormat("hh:mm", Locale.US).parse(close);
			int closeMinute = date.getHours()*60 + date.getMinutes();
			Integer[] times = {openMinute, closeMinute};

			hours.put(day,times);
		} catch (ParseException e) {
			return 1;
		}
		return 0;
	}
	
	/** Check if a toilet is open. */
	@SuppressWarnings("deprecation")
	public boolean isOpen() {
		Date now = new Date();
		int nowMinute = now.getHours()*60 + now.getMinutes();
		int day = now.getDay();
		Integer[] times = hours.get(weekdays[day]);
		int open = times[0];
		int close = times[1];
		if (nowMinute > open && nowMinute < close)
			return true;
		return false;
	}
	
	/** Set a toilet's rating. */
	public void setRating(float rating) {
		this.rating = rating;
	}
	
	/** Get a toilet's rating. */
	public float getRating() {
		return rating;
	}
	
	/** Get the number of votes. */
	public void setVotes(int votes) {
		this.votes = votes;
	}

	/** Get the number of votes. */
	public int getVotes() {
		return votes;
	}
	
	/** Set a toilet's photo. */
	public void setPhoto(String path) {
		photo = path;
	}
	
	/** Get a toilet's photo. */
	public String getPhoto() {
		return photo;
	}

	public LinkedList<Comment> getComments() {
		// TODO Auto-generated method stub
		return comments;
	}

	public void addComment(Comment comment) {
		if (comments == null)
			comments = new LinkedList<Comment>();
		if (comment != null)
			comments.add(comment);
	}
}
